
// 三种状态
const PENDING = 'pending';
const FUFILLED = 'fulfilled';
const REJECTDE = 'rejected';

function MPromise(executor){ // promise需要传入一个方法，并且创建promise实例时立即执行
    var _this = this;
    this.state = PENDING; // 初始状态为执行态
    this.value = undefined; // 用来存放回调函数执行成功的结果
    this.reason = undefined; // 用来存放回调函数执行失败的原因

    this.onFufilledCallback = [];
    this.onRejectedCallback = [];
    function resolve(value){ // 表示成功时的回调
        if(_this.state === PENDING){ // 只能在pending状态时转为fufilled，不可逆
            _this.state = FUFILLED;
            _this.value = value;
            _this.onFufilledCallback.forEach(fn=>{
                fn(value)
            })
        }
    }

    function rejecte(reason){ // 表示失败时的回调
        if(_this.state === PENDING){ // 只能在pending状态时转为rejected，不可逆
            _this.state = REJECTDE;
            _this.reason = reason;
            _this.onRejectedCallback.forEach(fn=>{
                fn(reason)
            })
        }
    }

    try{
        executor(resolve,rejecte) // 当创建promise实例时，就会立马执行promise，需要传进两个函数
    }catch(err){
        // throw new Error(err)
        reject(e)
    }
}


MPromise.prototype.then = function(onFufilled,onRejected){ // promise对外暴露出then方法，挂在原型链上
    const _this = this;
    let promise2 = new MPromise((resolve,reject)=>{
        onFufilled = typeof onFufilled === 'function' ? onFufilled : value=>value;
        onRejected = typeof onRejected === 'function' ? onRejected : reason=>reason;
        if(_this.state === FUFILLED){
            // 保持上一个函数的值
            let x = onFufilled(_this.value)
            // 并将值传递给下一个then
            if(x instanceof MPromise){
                x.then(resolve.reject)
            }else{
                resolve(x);
            }
        }
        if(_this.state === REJECTDE){
            onRejected(this.reason)
        }
        if(_this.state === PENDING){ // pending状态时先将回调存起来，等状态发生改变时进行调用
            this.onFufilledCallback.push(onFufilled)
            this.onRejectedCallback.push(onRejected)
        }
    })
    return promise2;
}

const p = new MPromise((resolve,reject)=>{
    resolve(222)
})

p.then((value)=>{
    console.log('then1====',value)
    return 999
}).then(res=>{
    console.log('then3====',res)
})
